import mongoose, { Schema, Document } from 'mongoose';

/**
 * 知识库文章类型
 */
export enum KnowledgeType {
  SOLUTION = 'solution',         // 解决方案
  BEST_PRACTICE = 'best_practice', // 最佳实践
  TROUBLESHOOTING = 'troubleshooting', // 故障排查
  FAQ = 'faq',                   // 常见问题
  RUNBOOK = 'runbook',           // 运维手册
}

/**
 * 知识库状态
 */
export enum KnowledgeStatus {
  DRAFT = 'draft',       // 草稿
  PUBLISHED = 'published', // 已发布
  ARCHIVED = 'archived',   // 已归档
}

/**
 * 知识库评分
 */
export interface IKnowledgeRating {
  userId: mongoose.Types.ObjectId;
  userName: string;
  rating: number;  // 1-5 星
  comment?: string;
  ratedAt: Date;
}

/**
 * 知识库接口定义
 */
export interface IKnowledge extends Document {
  _id: mongoose.Types.ObjectId;

  // 基本信息
  title: string;              // 标题
  content: string;            // 内容（Markdown 格式）
  summary: string;            // 摘要
  type: KnowledgeType;       // 类型
  status: KnowledgeStatus;   // 状态

  // 分类和标签
  category: string;          // 分类（如：数据库、网络、应用等）
  tags: string[];           // 标签

  // 关联信息
  relatedAlerts?: string[];        // 相关告警名称
  relatedTickets?: mongoose.Types.ObjectId[]; // 相关工单

  // 作者信息
  author: mongoose.Types.ObjectId;
  authorName: string;
  contributors: {             // 贡献者
    userId: mongoose.Types.ObjectId;
    userName: string;
    contributedAt: Date;
  }[];

  // 评分和反馈
  ratings: IKnowledgeRating[];
  averageRating: number;      // 平均评分
  helpfulCount: number;       // 有帮助的数量

  // 使用统计
  viewCount: number;          // 浏览次数
  usedCount: number;          // 使用次数（被引用到工单中的次数）

  // 版本控制
  version: number;
  previousVersions?: {
    version: number;
    content: string;
    updatedBy: mongoose.Types.ObjectId;
    updatedAt: Date;
  }[];

  // 时间戳
  createdAt: Date;
  updatedAt: Date;
  publishedAt?: Date;
  archivedAt?: Date;

  // Instance methods
  publish(): Promise<this>;
  archive(): Promise<this>;
  addRating(userId: mongoose.Types.ObjectId, userName: string, rating: number, comment?: string): Promise<this>;
  incrementViewCount(): Promise<this>;
  incrementUsedCount(): Promise<this>;
  updateContent(newContent: string, updatedBy: mongoose.Types.ObjectId): Promise<this>;
}

/**
 * 知识库数据模型
 */
const KnowledgeSchema = new Schema<IKnowledge>(
  {
    title: {
      type: String,
      required: true,
      trim: true,
      maxlength: 200,
      index: 'text',
    },
    content: {
      type: String,
      required: true,
      index: 'text',
    },
    summary: {
      type: String,
      required: true,
      trim: true,
      maxlength: 500,
    },
    type: {
      type: String,
      enum: Object.values(KnowledgeType),
      required: true,
      index: true,
    },
    status: {
      type: String,
      enum: Object.values(KnowledgeStatus),
      default: KnowledgeStatus.DRAFT,
      index: true,
    },

    // 分类和标签
    category: {
      type: String,
      required: true,
      trim: true,
      index: true,
    },
    tags: {
      type: [String],
      default: [],
      index: true,
    },

    // 关联信息
    relatedAlerts: {
      type: [String],
      default: [],
    },
    relatedTickets: {
      type: [Schema.Types.ObjectId],
      ref: 'Ticket',
      default: [],
    },

    // 作者信息
    author: {
      type: Schema.Types.ObjectId,
      ref: 'User',
      required: true,
      index: true,
    },
    authorName: {
      type: String,
      required: true,
    },
    contributors: {
      type: [
        {
          userId: {
            type: Schema.Types.ObjectId,
            ref: 'User',
            required: true,
          },
          userName: {
            type: String,
            required: true,
          },
          contributedAt: {
            type: Date,
            default: Date.now,
          },
        },
      ],
      default: [],
    },

    // 评分
    ratings: {
      type: [
        {
          userId: {
            type: Schema.Types.ObjectId,
            ref: 'User',
            required: true,
          },
          userName: {
            type: String,
            required: true,
          },
          rating: {
            type: Number,
            required: true,
            min: 1,
            max: 5,
          },
          comment: {
            type: String,
            default: null,
          },
          ratedAt: {
            type: Date,
            default: Date.now,
          },
        },
      ],
      default: [],
    },
    averageRating: {
      type: Number,
      default: 0,
      min: 0,
      max: 5,
    },
    helpfulCount: {
      type: Number,
      default: 0,
    },

    // 统计
    viewCount: {
      type: Number,
      default: 0,
    },
    usedCount: {
      type: Number,
      default: 0,
    },

    // 版本
    version: {
      type: Number,
      default: 1,
    },
    previousVersions: {
      type: [
        {
          version: {
            type: Number,
            required: true,
          },
          content: {
            type: String,
            required: true,
          },
          updatedBy: {
            type: Schema.Types.ObjectId,
            ref: 'User',
            required: true,
          },
          updatedAt: {
            type: Date,
            default: Date.now,
          },
        },
      ],
      default: [],
    },

    publishedAt: {
      type: Date,
      default: null,
    },
    archivedAt: {
      type: Date,
      default: null,
    },
  },
  {
    timestamps: true,
    versionKey: false,
  }
);

/**
 * 全文搜索索引
 */
KnowledgeSchema.index({ title: 'text', content: 'text', summary: 'text' });

/**
 * 复合索引
 */
KnowledgeSchema.index({ status: 1, type: 1 });
KnowledgeSchema.index({ category: 1, status: 1 });
KnowledgeSchema.index({ tags: 1, status: 1 });
KnowledgeSchema.index({ averageRating: -1, viewCount: -1 });

/**
 * 实例方法：发布文章
 */
KnowledgeSchema.methods.publish = function () {
  this.status = KnowledgeStatus.PUBLISHED;
  this.publishedAt = new Date();
  return this.save();
};

/**
 * 实例方法：归档文章
 */
KnowledgeSchema.methods.archive = function () {
  this.status = KnowledgeStatus.ARCHIVED;
  this.archivedAt = new Date();
  return this.save();
};

/**
 * 实例方法：添加评分
 */
KnowledgeSchema.methods.addRating = function (
  userId: mongoose.Types.ObjectId,
  userName: string,
  rating: number,
  comment?: string
) {
  // 检查用户是否已评分
  const existingRatingIndex = this.ratings.findIndex(
    (r: IKnowledgeRating) => r.userId.toString() === userId.toString()
  );

  if (existingRatingIndex > -1) {
    // 更新已有评分
    this.ratings[existingRatingIndex] = {
      userId,
      userName,
      rating,
      comment,
      ratedAt: new Date(),
    };
  } else {
    // 添加新评分
    this.ratings.push({
      userId,
      userName,
      rating,
      comment,
      ratedAt: new Date(),
    });
  }

  // 重新计算平均评分
  this.averageRating =
    this.ratings.reduce((sum: number, r: IKnowledgeRating) => sum + r.rating, 0) /
    this.ratings.length;

  return this.save();
};

/**
 * 实例方法：增加浏览次数
 */
KnowledgeSchema.methods.incrementViewCount = function () {
  this.viewCount += 1;
  return this.save();
};

/**
 * 实例方法：增加使用次数
 */
KnowledgeSchema.methods.incrementUsedCount = function () {
  this.usedCount += 1;
  return this.save();
};

/**
 * 实例方法：更新内容（保留历史版本）
 */
KnowledgeSchema.methods.updateContent = function (
  newContent: string,
  userId: mongoose.Types.ObjectId
) {
  // 保存当前版本到历史
  this.previousVersions.push({
    version: this.version,
    content: this.content,
    updatedBy: userId,
    updatedAt: new Date(),
  });

  // 更新内容和版本号
  this.content = newContent;
  this.version += 1;

  return this.save();
};

/**
 * 静态方法：搜索知识库
 */
KnowledgeSchema.statics.search = function (
  keyword: string,
  filters?: {
    type?: KnowledgeType;
    category?: string;
    tags?: string[];
  }
) {
  const query: any = {
    status: KnowledgeStatus.PUBLISHED,
    $text: { $search: keyword },
  };

  if (filters?.type) {
    query.type = filters.type;
  }
  if (filters?.category) {
    query.category = filters.category;
  }
  if (filters?.tags && filters.tags.length > 0) {
    query.tags = { $in: filters.tags };
  }

  return this.find(query, { score: { $meta: 'textScore' } })
    .sort({ score: { $meta: 'textScore' } })
    .limit(20);
};

/**
 * 静态方法：获取热门文章
 */
KnowledgeSchema.statics.findPopular = function (limit = 10) {
  return this.find({ status: KnowledgeStatus.PUBLISHED })
    .sort({ viewCount: -1, averageRating: -1 })
    .limit(limit);
};

export default mongoose.model<IKnowledge>('Knowledge', KnowledgeSchema);
